home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 975 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.8 KB  |  183 lines

  1. Path: atglab.bls.com!Alun.Champion
  2. From: Alun.Champion@bridge.bst.bls.com (Alun Champion)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: allocating unlimited string input....HELP
  5. Date: 10 Jan 1996 16:27:33 GMT
  6. Organization: Computer People Inc.
  7. Message-ID: <ALUN.CHAMPION.96Jan10112733@g7240065.bridge.bst.bls.com>
  8. References: <4d0e2c$4uq@clientlink.com>
  9. NNTP-Posting-Host: bstfirewall.bst.bls.com
  10. In-reply-to: Matthew Raffel's message of 10 Jan 1996 13:13:48 GMT
  11.  
  12. In article <4d0e2c$4uq@clientlink.com> Matthew Raffel <raffelm@netcom.com> writes:
  13.  
  14. : ryangall@gpu.srv.ualberta.ca (Bobby Sixkiller) writes:
  15.  
  16. : A few things I may consider note worthy:
  17.  
  18. : You need test B for a vailidity as a pointer.
  19. : EG: 
  20. : if (!B) 
  21. :    printf("\nMalloc Failed");
  22.  
  23. : Additionally, you are never freeing B before "realloc"ing
  24. : it.  What is happening here, B gets set to point to
  25. : some hunk of memory, then gets pointed to another hunk
  26. : and another and so on.  The pieces of memory B pointed to
  27. : a one point is never released back to the system.  This could
  28. : be the cause of the failure after a fixed point, especially
  29. : if you are compiling in a small or compact memory model.
  30.  
  31. In his original code - he never used realloc, you mean re-malloc. He assigned
  32. B to A and free'd A in the loop. The memory was not the cause for failure.
  33.  
  34. : You can avoid "needing" A by using realloc which 
  35. : will preserve the contents of the memory.
  36.  
  37. : Below is a "rewrite" of your code to implement my thoughts.
  38. : One, note, I did not compile it so...look out :=)
  39.  
  40. :  int read(char *S)
  41.  
  42. Probably not a good choice of name, though not defined in the standards many
  43. operating systems define their own read() and write() functions.
  44.  
  45. :  {
  46. :   char *B = NULL;
  47. :   char ch,count=0;
  48.  
  49. This is more likely to be the cause of the failure, count is a char, which may
  50. be a signed char (implementation defined) and if this is the case has max value
  51. of 127 and would then wrap and become negative - this could cause a few
  52. problems. If it is not signed then its maximum value is 255 which is not
  53. really big enough to deal with strings of unlimited length ;')
  54.  
  55. :   int  iCount = 0;
  56.  
  57. :    /* create an initial size */
  58. :    B = malloc(6);
  59.  
  60. The test for the malloc is buried deep in the loop
  61.  
  62. :    ch=getc(stdin);
  63.  
  64. getc(stdin) is equivalent to getchar() and returns an int not a char.
  65.  
  66. :    while(ch!='\n')
  67.  
  68. Should test EOF condition, for this reason getc() returns an int and not char.
  69.  
  70. :    {
  71. :    /* only realloc every so often...increment memory size by 5 bytes each time
  72. :    if (iCount == 5)
  73.  
  74. Hard coding values is probably not a good idea.
  75.  
  76. :    {
  77. :      B=(char *) realloc(B, count + 5);
  78.  
  79. Cast is unnecessary in ansi C and should be removed. If the realloc fails
  80. you lose the space pointed to by B - a memory leak perhaps.
  81.  
  82. :      iCount = 0;
  83. :    }
  84. :    else
  85. :      iCount ++;
  86.  
  87. :    if (!B)
  88. :    {
  89. :      printf("\nB does not exist");
  90.  
  91. The '\n' should be at the end of the string or else you should explicitly flush
  92. the output.
  93.  
  94. :      break;
  95. :    } 
  96. :    else
  97. :    {
  98. :      sprintf(B,"%s%c",B,ch);
  99.  
  100. This is quite innefficient now as realloc retains the contents of B for you
  101.           B[count] = ch;
  102.           B[count+1] = '\0';
  103. and the '\0' terminating character is not accounted for in the realloc but
  104. it is in the malloc. You would have to add one to the realloc(). And it
  105. was not dealt with in the original program.
  106.  
  107. :      printf("%s---%i----%i\n",B,strlen(B),count);
  108. :    }
  109. :    ch=getc(stdin);
  110.  
  111. if this was placed in the while expression you wouldn't need to repeat this
  112. statement.
  113.  
  114. :    count=count+1;
  115.  
  116. Whats wrong with the increment operator ?;')
  117.         count++;
  118.  
  119. :    }
  120.  
  121. :   /* copy results to return value */
  122. :   if (S && B)
  123. :    strcpy(S, B);
  124.  
  125. This is probably not what the original poster wanted because this assumes he
  126. new the maximum size of the string when coming into the function, which
  127. is not the case as this is supposed to handle strings of unlimited length.
  128. What he probably wanted was read() to return a char* or to take a char**
  129. and then would either return B or assign the value of B to S i.e:
  130.  
  131.       return B;
  132. or
  133.       *S = B;
  134.  
  135. Missing return statement and in your example B needs to be free'd.
  136.      free(B);
  137.      return 1;
  138. :  }
  139.  
  140.  
  141. My turn ;'):
  142. [* warning untested code. *]
  143.  
  144. char*
  145. readString(void)
  146. {
  147.     int ch;
  148.     long count = 0;
  149.     long size = 20;          /* initial size */
  150.     const int increment = 16;
  151.     char* B = 0;
  152.  
  153.     B = malloc(size);
  154.     if (!B)
  155.         return 0;
  156.  
  157.     while ((ch = getchar()) != EOF && ch != '\n') {
  158.         if (count == size - 1) {
  159.             char* A = realloc(B, size += increment);
  160.             if (!A) {
  161.                 free(B);
  162.                 return 0;
  163.             } else {
  164.                 B = A;
  165.             }
  166.         }
  167.         B[count++] = (char)ch;
  168.     }
  169.  
  170. /* There is a slight fudge in the condition for the realloc() that guarentees */
  171. /* one character spare for this assignment */
  172.     B[count] = '\0';
  173.  
  174.     return B;
  175. }
  176.  
  177. Hope this works ;')
  178. Regards
  179.  
  180.     -A.
  181. -- 
  182. | A.Champion                |
  183.